package cloud.xlh.dynamic_env_refresh_server.controller;

import cloud.xlh.dynamic_env_refresh_server.ConcurrentHashSet;
import cloud.xlh.dynamic_env_refresh_server.NotifyCenter;
import cloud.xlh.dynamic_env_refresh_server.event.LocalDataChangeEvent;
import cloud.xlh.dynamic_env_refresh_server.event.Subscriber;
import cloud.xlh.dynamic_env_refresh_server.service.LongPollingService;
import cloud.xlh.infrastructure.utils.FileUtil;
import cloud.xlh.infrastructure.utils.StringUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.StringJoiner;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2023/3/19 15:52
 * @ Description: 配置发布
 */
@RestController
@RequestMapping("/publishController")
public class PublishController {

    @Autowired
    private LongPollingService longPollingService;

    @Value("${remote.serviceCallListFile.location}")
    private String remoteServiceCallListFileLocation;

    @PostMapping("/publish")
    public JSONObject publish(@RequestBody JSONObject jsonObject) {
        NotifyCenter notifyCenter = longPollingService.getNotifyCenter();
        String config = (String)jsonObject.get("config");
        //读取远程磁盘配置
       /* String config2JsonString = FileUtil.readCommonFileAndToStr(FileUtil.PathTypeCode.ABSOLUTE_PATH.getCode(), remoteServiceCallListFileLocation);
        String valueFromRemote = JSONObjectUtil.getAnyNodeDataFromJsonStr(config2JsonString, "svcCode");
*/
        Map map = FileUtil.readFromJsonFile(remoteServiceCallListFileLocation, null);
        String valueFromRemote = (String) map.get("svcCode");
        //发布的配置与远程本地磁盘配置不一致才会发布事件和更新本地磁盘中配置信息
        if (!StringUtil.isEmpty(valueFromRemote) && !valueFromRemote.equals(config)) {
            //覆盖远程磁盘中配置
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(remoteServiceCallListFileLocation);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            StringBuilder configStringBuilder = new StringBuilder("\"svcCode\":");
            configStringBuilder = configStringBuilder.append("\"" + config + "\"");
            StringJoiner stringJoiner = new StringJoiner("", "{", "}");
            String configStr = stringJoiner.add(configStringBuilder.toString()).toString();
            byte[] config2Bytes = configStr.getBytes();
            int length = config2Bytes.length;
            try {
                bufferedOutputStream.write(config2Bytes , 0 , length);
                bufferedOutputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }

            //发布事件
            ConcurrentHashSet<Subscriber> subscribers = notifyCenter.getSubscribers();
            Iterator<Subscriber> iterator = subscribers.iterator();
            while (iterator.hasNext()) {
                Subscriber next = iterator.next();
                LocalDataChangeEvent localDataChangeEvent = new LocalDataChangeEvent("svcCode" , null);
                next.onEvent(localDataChangeEvent);
            }
        }

        JSONObject rspJsonObject = new JSONObject();
        JSONObject rspHead = new JSONObject();
        JSONObject rspBody = new JSONObject();
        rspHead.put("retCode" , "PR01");
        rspHead.put("retInfo" , "发布成功");
        rspBody.put("changData" , config);
        rspJsonObject.put("head" , rspHead);
        rspJsonObject.put("body" , rspBody);
        return rspJsonObject;
    }
}
